<template>
  <div class="role-manage">
    <!-- 搜索和筛选区域 -->
    <div class="search-filter">
      <div class="search-item">
        <span class="label">角色名称</span>
        <el-input v-model="searchForm.name" placeholder="请输入角色名称" clearable></el-input>
      </div>
      <div class="search-item">
        <span class="label">状态</span>
        <el-select v-model="searchForm.status" placeholder="角色状态" clearable>
          <el-option label="正常" value="1"></el-option>
          <el-option label="停用" value="0"></el-option>
        </el-select>
      </div>
      <el-button type="primary" @click="onSearch" class="search-btn">
        <el-icon><Search /></el-icon>搜索
      </el-button>
      <el-button @click="onReset" class="reset-btn">
        <el-icon><Refresh /></el-icon>重置
      </el-button>
    </div>

    <!-- 操作按钮区域 -->
    <div class="operation-btns">
      <el-button type="primary" plain @click="handleAdd" class="add-btn">
        <el-icon><Plus /></el-icon>新增
      </el-button>
      <div class="right-btns">
        <el-icon class="refresh-icon" @click="getRoleListData"><RefreshRight /></el-icon>
        <el-icon class="setting-icon"><Setting /></el-icon>
      </div>
    </div>

    <!-- 角色列表 -->
    <el-table :data="roleList" style="width: 100%" row-key="id" :row-style="{ height: '50px' }" border>
      <el-table-column prop="name" label="角色名称" min-width="80"></el-table-column>
      <el-table-column prop="roleKey" label="权限字符" min-width="80"></el-table-column>
      <el-table-column prop="remark" label="备注" min-width="220"></el-table-column>
      <el-table-column prop="status" label="状态" width="100" align="center">
        <template #default="scope">
          <el-tag :type="scope.row.status === 1 ? 'success' : 'info'" effect="light">
            {{ scope.row.status === 1 ? "正常" : "停用" }}
          </el-tag>
        </template>
      </el-table-column>
      <el-table-column prop="createTime" label="创建时间" min-width="160"></el-table-column>
      <el-table-column label="操作" width="260" fixed="right">
        <template #default="scope">
          <el-link type="primary" @click="handleEdit(scope.row)" class="operation-link">
            <el-icon><Edit /></el-icon>修改
          </el-link>
          <el-link
            v-if="scope.row.roleKey !== 'ADMIN'"
            type="primary"
            @click="handlePermission(scope.row)"
            class="operation-link"
          >
            <el-icon><Key /></el-icon>权限
          </el-link>
          <el-link v-if="!isAdmin(scope.row)" type="danger" @click="handleDelete(scope.row)" class="operation-link">
            <el-icon><Delete /></el-icon>删除
          </el-link>
          <el-link v-if="!isAdmin(scope.row)" type="primary" @click="handleStatus(scope.row)" class="operation-link">
            <el-icon v-if="scope.row.status === 1"><CircleClose /></el-icon>
            <el-icon v-else><Check /></el-icon>
            {{ scope.row.status === 1 ? "停用" : "启用" }}
          </el-link>
        </template>
      </el-table-column>
    </el-table>

    <!-- 角色表单弹窗 -->
    <el-dialog
      :title="dialogTitle"
      v-model="dialogVisible"
      width="600px"
      :close-on-click-modal="false"
      :before-close="handleDialogClose"
    >
      <el-form
        :model="roleForm"
        :rules="roleFormRules"
        ref="roleFormRef"
        label-width="100px"
        @submit.prevent="submitForm"
      >
        <el-form-item label="角色名称" prop="name">
          <el-input v-model="roleForm.name" placeholder="请输入角色名称"></el-input>
        </el-form-item>
        <el-form-item label="权限字符" prop="roleKey">
          <el-input v-model="roleForm.roleKey" placeholder="请输入权限字符"></el-input>
        </el-form-item>
        <el-form-item label="状态" prop="status">
          <el-radio-group v-model="roleForm.status">
            <el-radio :label="1">正常</el-radio>
            <el-radio :label="0">停用</el-radio>
          </el-radio-group>
        </el-form-item>
        <el-form-item label="备注" prop="remark">
          <el-input v-model="roleForm.remark" type="textarea" :rows="3" placeholder="请输入备注"></el-input>
        </el-form-item>
      </el-form>
      <template #footer>
        <span class="dialog-footer">
          <el-button @click="handleDialogClose">取 消</el-button>
          <el-button type="primary" @click.native.prevent="submitForm" :loading="submitLoading">确 定</el-button>
        </span>
      </template>
    </el-dialog>

    <!-- 分配权限弹窗 -->
    <el-dialog
      title="分配权限"
      v-model="permissionDialogVisible"
      width="600px"
      :close-on-click-modal="false"
      :before-close="handlePermissionDialogClose"
    >
      <el-form :model="permissionForm" label-width="100px">
        <el-form-item label="角色名称">
          <span>{{ permissionForm.name }}</span>
        </el-form-item>
        <el-form-item label="权限分配">
          <el-tree
            ref="permissionTreeRef"
            :data="permissionTree"
            :props="{ children: 'children', label: 'label' }"
            show-checkbox
            node-key="id"
            :default-checked-keys="checkedPermissions"
            highlight-current
            default-expand-all
          >
            <template #default="{ node, data }">
              <span class="custom-tree-node">
                <el-icon v-if="data.icon" class="menu-icon">
                  <component :is="getIconComponent(data.icon)" />
                </el-icon>
                <span class="menu-label">{{ node.label }}</span>
              </span>
            </template>
          </el-tree>
        </el-form-item>
      </el-form>
      <template #footer>
        <span class="dialog-footer">
          <el-button @click="handlePermissionDialogClose">取 消</el-button>
          <el-button type="primary" @click="submitPermissions">确 定</el-button>
        </span>
      </template>
    </el-dialog>
  </div>
</template>

<script setup>
import { ref, reactive, onMounted, computed, nextTick } from "vue";
import { ElMessage, ElMessageBox } from "element-plus";
import {
  Search,
  Refresh,
  Plus,
  Setting,
  Delete,
  Edit,
  RefreshRight,
  Key,
  CircleClose,
  Check,
} from "@element-plus/icons-vue";
import * as ElementPlusIconsVue from "@element-plus/icons-vue";
import {
  getRoleList,
  addRole,
  updateRole,
  deleteRole,
  updateRoleStatus,
  getRolePermissions,
  updateRolePermissions,
} from "@/api/role";
import { getMenuList } from "@/api/menu";
import { selectUserPermissions } from "@/api/role";

// 角色列表数据
const roleList = ref([]);

// 搜索表单数据
const searchForm = ref({
  name: "",
  status: "",
});

// 角色弹窗相关
const dialogVisible = ref(false);
const dialogType = ref("add"); // add 或 edit
const dialogTitle = computed(() => {
  return dialogType.value === "add" ? "新增角色" : "编辑角色";
});
const roleFormRef = ref(null);

// 角色表单数据
const defaultRoleForm = {
  id: undefined,
  name: "",
  roleKey: "",
  status: 1,
  remark: "",
};

const roleForm = ref({ ...defaultRoleForm });

// 表单验证规则
const roleFormRules = {
  name: [
    { required: true, message: "角色名称不能为空", trigger: "blur" },
    { min: 2, max: 50, message: "角色名称长度应在2-50个字符之间", trigger: "blur" },
  ],
  roleKey: [
    { required: true, message: "权限字符不能为空", trigger: "blur" },
    { min: 2, max: 100, message: "权限字符长度应在2-100个字符之间", trigger: "blur" },
    { pattern: /^[a-zA-Z0-9_]+$/, message: "权限字符只能包含字母、数字和下划线", trigger: "blur" },
  ],
  status: [{ required: true, message: "状态不能为空", trigger: "change" }],
};

// 权限分配相关
const permissionDialogVisible = ref(false);
const permissionForm = ref({
  id: "",
  name: "",
});
const permissionTree = ref([]);
const checkedPermissions = ref([]);
const permissionTreeRef = ref(null);

// 控制提交按钮状态
const submitLoading = ref(false);

// 获取角色列表数据
const getRoleListData = async () => {
  try {
    const response = await getRoleList(searchForm.value);
    if (response.success) {
      roleList.value = response.data.list || [];
      console.log("角色列表数据:", roleList.value);
    } else {
      ElMessage.error(response.message || "获取角色列表失败");
    }
  } catch (error) {
    console.error("获取角色列表出错:", error);
    ElMessage.error("获取角色列表失败");
  }
};

// 搜索功能
const onSearch = () => {
  getRoleListData();
};

// 重置功能
const onReset = () => {
  searchForm.value = {
    name: "",
    status: "",
  };
  getRoleListData();
};

// 重置表单
const resetForm = (completeReset = true) => {
  // 如果是完全重置，则使用默认值
  if (completeReset) {
    // 使用深拷贝确保完全重置
    roleForm.value = JSON.parse(JSON.stringify(defaultRoleForm));
  }

  // 延迟重置字段，确保DOM已更新
  nextTick(() => {
    if (roleFormRef.value) {
      // 只清除验证状态，不重置值
      roleFormRef.value.clearValidate();
    }
  });
};

// 关闭弹窗
const handleDialogClose = () => {
  resetForm(true); // 完全重置表单
  dialogVisible.value = false;
};

// 添加角色
const handleAdd = () => {
  dialogType.value = "add";
  // 完全重置表单
  resetForm(true);
  dialogVisible.value = true;
};

// 编辑角色
const handleEdit = (row) => {
  dialogType.value = "edit";
  // 不完全重置表单，只清除验证状态
  resetForm(false);

  // 先打印原始数据
  console.log("原始行数据:", JSON.stringify(row));

  // 创建一个新对象，避免引用问题
  const editData = {
    id: row.id,
    name: row.name || "",
    roleKey: row.roleKey || "",
    status: row.status !== undefined ? Number(row.status) : 1,
    remark: row.remark || "",
  };

  // 确保每个字段都有正确的类型和默认值
  if (editData.status !== 0 && editData.status !== 1) {
    editData.status = 1; // 默认为正常状态
  }

  console.log("处理后的编辑数据:", JSON.stringify(editData));

  // 使用处理后的数据更新表单
  roleForm.value = editData;

  // 延迟检查表单数据是否正确设置
  nextTick(() => {
    console.log("表单数据设置后:", JSON.stringify(roleForm.value));
    dialogVisible.value = true;
  });
};

// 删除角色
const handleDelete = (row) => {
  ElMessageBox.confirm(`确定删除角色 "${row.name}" 吗？删除后无法恢复！`, "警告", {
    confirmButtonText: "确定",
    cancelButtonText: "取消",
    type: "warning",
  })
    .then(async () => {
      try {
        const response = await deleteRole(row.id);
        if (response.success) {
          ElMessage.success("删除成功");
          getRoleListData();
        } else {
          ElMessage.error(response.message || "删除失败");
        }
      } catch (error) {
        console.error("删除角色出错:", error);
        ElMessage.error("删除失败");
      }
    })
    .catch(() => {
      // 取消删除
    });
};

onMounted(() => {
  const res = selectUserPermissions();
  if (res.success) {
    localStorage.setItem("permissions", JSON.stringify(res.data));
  }
});

// 提交表单
const submitForm = async () => {
  // 手动触发提交事件
  console.log("提交按钮被点击");

  // 防止重复提交
  if (submitLoading.value) {
    console.log("正在提交中，请勿重复点击");
    return;
  }

  submitLoading.value = true;
  console.log("开始提交表单");

  if (!roleFormRef.value) {
    console.error("表单引用不存在");
    ElMessage.error("表单引用不存在，请刷新页面重试");
    submitLoading.value = false;
    return;
  }

  // 尝试直接提交数据，跳过表单验证
  if (dialogType.value === "edit") {
    try {
      const submitData = {
        ...roleForm.value,
        status: Number(roleForm.value.status),
      };

      console.log("直接提交编辑数据:", submitData);
      const response = await updateRole(submitData);

      if (response.success) {
        ElMessage.success("修改成功");
        dialogVisible.value = false;
        getRoleListData();
        submitLoading.value = false;
        return;
      }
    } catch (directError) {
      console.error("直接提交失败，尝试常规验证流程:", directError);
      // 继续执行下面的验证流程
    }
  }

  // 正常验证流程
  try {
    // 手动触发表单验证
    const valid = await roleFormRef.value.validate().catch((err) => {
      console.error("表单验证失败:", err);
      return false;
    });

    if (!valid) {
      console.error("表单验证未通过");
      ElMessage.error("表单验证失败，请检查输入");
      submitLoading.value = false;
      return;
    }

    console.log("表单验证通过，准备提交数据");
    const isAdd = dialogType.value === "add";

    // 确保数据类型正确
    const submitData = {
      ...roleForm.value,
      status: Number(roleForm.value.status), // 确保状态是数字类型
    };

    // 删除不需要的字段
    if (isAdd) {
      delete submitData.id; // 添加时不需要ID
      delete submitData.createTime; // 添加时不需要创建时间
      delete submitData.updateTime; // 添加时不需要更新时间
    }

    console.log("提交数据:", submitData);

    // 避免网络问题或请求超时造成的问题
    const api = isAdd ? addRole : updateRole;
    const res = selectUserPermissions();
    if (res.success) {
      localStorage.setItem("permissions", JSON.stringify(res.data));
    }
    try {
      console.log("发送请求中...");
      const response = await Promise.race([
        api(submitData),
        new Promise((_, reject) => setTimeout(() => reject(new Error("请求超时")), 10000)),
      ]);

      console.log("收到响应:", response);
      if (response.success) {
        ElMessage.success(isAdd ? "添加成功" : "修改成功");
        dialogVisible.value = false;
        getRoleListData();
      } else {
        ElMessage.error(response.message || (isAdd ? "添加失败" : "修改失败"));
      }
    } catch (apiError) {
      console.error("API请求出错:", apiError);
      ElMessage.error(`${isAdd ? "添加" : "修改"}失败: ${apiError.message || "未知错误"}`);
    }
  } catch (error) {
    console.error("表单处理出错:", error);
    ElMessage.error(`表单处理失败: ${error.message || "未知错误"}`);
  } finally {
    submitLoading.value = false;
  }
};

// 处理角色状态变更
const handleStatus = async (row) => {
  const statusText = row.status === 1 ? "停用" : "启用";
  try {
    const newStatus = row.status === 1 ? 0 : 1;
    const response = await updateRoleStatus({
      id: row.id,
      status: newStatus,
    });

    if (response.success) {
      ElMessage.success(`${statusText}成功`);
      getRoleListData();
    } else {
      ElMessage.error(response.message || `${statusText}失败`);
    }
  } catch (error) {
    console.error("更新角色状态出错:", error);
    ElMessage.error(`${statusText}失败`);
  }
};

// 判断是否是管理员角色
const isAdmin = (role) => {
  return role.roleKey === "ADMIN";
};

// 权限分配
const handlePermission = async (row) => {
  permissionForm.value = {
    id: row.id,
    name: row.name,
  };

  try {
    // 获取权限树
    const menuResponse = await getMenuList();
    if (menuResponse.success) {
      permissionTree.value = menuResponse.data || [];
    } else {
      ElMessage.error(menuResponse.message || "获取权限树失败");
      return;
    }

    // 获取角色已有权限
    const permissionsResponse = await getRolePermissions(row.id);
    if (permissionsResponse.success) {
      checkedPermissions.value = permissionsResponse.data || [];
      console.log(checkedPermissions.value);
    } else {
      ElMessage.error(permissionsResponse.message || "获取角色权限失败");
      return;
    }

    permissionDialogVisible.value = true;
  } catch (error) {
    console.error("获取权限数据出错:", error);
    ElMessage.error("获取权限数据失败");
  }
};

// 关闭权限分配弹窗
const handlePermissionDialogClose = () => {
  permissionDialogVisible.value = false;
  permissionTree.value = [];
  checkedPermissions.value = [];
};

// 提交权限分配
const submitPermissions = async () => {
  if (!permissionTreeRef.value) return;

  try {
    // 当前选中节点
    const checkedKeys = permissionTreeRef.value.getCheckedKeys();
    // 半选中节点 父级节点 例如:选中的节点为父级节点的子节点且没有全部选中
    const halfCheckedKeys = permissionTreeRef.value.getHalfCheckedKeys();
    const allCheckedKeys = [...checkedKeys, ...halfCheckedKeys];

    const response = await updateRolePermissions({
      roleId: permissionForm.value.id,
      menuIds: allCheckedKeys,
    });

    if (response.success) {
      ElMessage.success("权限分配成功");
      permissionDialogVisible.value = false;
    } else {
      ElMessage.error(response.message || "权限分配失败");
    }
  } catch (error) {
    console.error("权限分配出错:", error);
    ElMessage.error("权限分配失败");
  }
};

// 动态加载图标组件
const getIconComponent = (iconName) => {
  if (!iconName) return null;
  return ElementPlusIconsVue[iconName];
};

onMounted(() => {
  getRoleListData();
});
</script>

<style scoped>
.role-manage {
  padding: 20px;
  background-color: #f5f7fa;
  min-height: calc(100vh - 84px);
}

/* 搜索过滤区样式 */
.search-filter {
  display: flex;
  align-items: center;
  padding: 18px 20px;
  background-color: #fff;
  border-radius: 4px;
  box-shadow: 0 1px 4px rgba(0, 0, 0, 0.05);
  margin-bottom: 16px;
}

.search-item {
  display: flex;
  align-items: center;
  margin-right: 15px;
}

.search-item .label {
  margin-right: 8px;
  font-size: 14px;
  color: #606266;
  white-space: nowrap;
}

.search-item :deep(.el-input),
.search-item :deep(.el-select) {
  width: 220px;
}

.search-btn,
.reset-btn {
  margin-right: 10px;
}

/* 操作按钮区域 */
.operation-btns {
  display: flex;
  align-items: center;
  margin-bottom: 16px;
}

.add-btn {
  margin-right: 10px;
}

.right-btns {
  display: flex;
  align-items: center;
  margin-left: auto;
}

.refresh-icon,
.setting-icon {
  font-size: 18px;
  margin-left: 15px;
  color: #606266;
  cursor: pointer;
}

.refresh-icon:hover,
.setting-icon:hover {
  color: #409eff;
}

/* 表格样式 */
.el-table {
  background-color: #fff;
  border-radius: 4px;
  box-shadow: 0 1px 4px rgba(0, 0, 0, 0.05);
}

:deep(.el-table__header) {
  background-color: #f5f7fa;
}

:deep(.el-table__header-wrapper th) {
  background-color: #f5f7fa;
  color: #606266;
  font-weight: 600;
  height: 50px;
}

:deep(.el-table__row td) {
  padding: 10px 0;
}

/* 操作列样式 */
.operation-link {
  display: inline-flex;
  align-items: center;
  margin-right: 12px;
  font-size: 13px;
}

.operation-link :deep(.el-icon) {
  margin-right: 3px;
  font-size: 14px;
}

/* 标签样式 */
:deep(.el-tag) {
  border-radius: 4px;
  padding: 0 10px;
  height: 28px;
  line-height: 28px;
}

/* 弹窗样式 */
:deep(.el-dialog) {
  border-radius: 8px;
}

:deep(.el-dialog__header) {
  border-bottom: 1px solid #f0f0f0;
  padding: 15px 20px;
}

:deep(.el-dialog__body) {
  padding: 20px;
}

:deep(.el-dialog__footer) {
  border-top: 1px solid #f0f0f0;
  padding: 15px 20px;
}

.dialog-footer {
  display: flex;
  justify-content: flex-end;
}

/* 树形控件样式 */
.custom-tree-node {
  display: flex;
  align-items: center;
}

.menu-icon {
  margin-right: 5px;
  font-size: 16px;
}

.menu-label {
  font-size: 14px;
}
</style>
